Day2的時候,我們直接寫出了一個簡單的Unity Shader,並沒有直接開始解釋Shader是甚麼東西,原因是我想試試看一開始不直接講理論,而是先給出一個可預期的結果讀者會怎麼想,畢竟從小到大我們接受過的教育基本上都是理論霹靂啪啦講一堆,最後不知所以的上去實作,這感覺很糟。
回到主題,今天就來聊聊,「甚麼是Shader?」
首先要說一下甚麼是圖形API...
學習Shader困難的地方除了數學以外,還有必須針對不同的平台進行處理,不同平台就有不同的圖形API,像是Windows的DirectX,macOS的Metal,khronos組織為了對應多平台的OpenGL及Vulken。
光是要了解渲染與數學知識,還要根據不同平台去學習,真心感覺學習Shader的門檻真的高。
但是Unity幫我們解決了這個問題,它在這些API上又抽象了一層語言,叫做ShaderLab,方便開發者一套Shader可以用一套寫法,執行在不同平台上。(事實上還是需要顧慮不同效能所擁有的問題)
在第二天的時候,我們的Shader中有一行#include UnityCG.cginc
。Unity Shader用類似C或C++的語法把Unity.cginc這份檔案匯入進來。
在vertex shader的地方有一句:
return UnityObjectToClipPos(v);
這個函式就是從UnityCG.cginc來的。
除了UnityCG.cginc,還有許多標頭檔,這些文件都存放在Unity的路徑底下,打開執行檔的資料夾後,點選:
Data -> CGIncludes
就可以找到了...
以下是UnityCG.cginc
的樣子。
裡面有大量的函式和結構方便我們在寫Shader時使用,而不用重頭將整個的矩陣運算重寫一遍。
簡單總結成一句話:
「Shader就是執行在GPU上的小程序,控制著GPU渲染管線,處理我們開發者給他的各種繪圖相關的資料,例如: 頂點位置、顏色、法向量」
以前總以為那些神奇精美的特效都是經過Shader,但坑採了之後才知道,這樣說法或許不對,是「所有跟渲染相關的都會經過Shader,哪怕只是畫一個簡單的點」。
《Real-Time Rendering, 3rd Edition》將繪製階段分成三個:應用階段、幾何階段、光柵化階段
應用階段是作用在CPU上的,該階段開發者有完全的控制權,場景上有多少物件,相機要是透視的還是正交的,那些要面剃除,這些都在應用階段完成;後兩個狀態,幾何和光柵化是作用GPU上的,視情況可能拆成兩篇來寫。
最後,來張圖表示直接表示CPU到GPU之間的溝通過程,也就是應用階段,我認為一張圖勝過千言萬語~
Day2的範例中,我們看到了vertex shader和fragment shader跟他們是在處理甚麼,其實還有許多可供我們控制的地方,明天會介紹GPU渲染管線是甚麼東西。